In [1]:
import csv
import numpy as np
import requests
import pandas as pd
import json
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.graph_objects as go   
import plotly.express as px

from matplotlib import font_manager, rc
plt.rcParams['axes.unicode_minus'] = False
f_path = "C://Windows//Fonts/malgun.ttf"
font_name = font_manager.FontProperties(fname=f_path).get_name()
rc('font', family=font_name)
In [2]:
#버스 행정동별 승차인원
busPP = pd.read_csv('./data/bus_congestion.csv', encoding='cp949')
busPP = busPP.drop(busPP.columns[0:2], axis=1)
busPP.head()
Out[2]:
행정동 승차인원
0 동선동 88065
1 와룡동 6787
2 종로1·2·3·4가동 39868
3 삼선동 60435
4 교남동 28437
In [3]:
#버스 행정동별 운행대수
busWK = pd.read_csv('./data/bus_work.csv')
busWK.head()
Out[3]:
행정동 운행대수
0 천호2동 1203
1 성내2동 962
2 암사1동 634
3 천호1동 1015
4 강일동 2364
In [4]:
#혼잡도 = 일일 승하차승객수 / 운행대수 -> 버스마다 크기와 좌석수가 다르기 때문에 어느정도의 오차가 발생할 수 있음
busResult = pd.merge(busPP, busWK, on='행정동', how='inner')
busResult['혼잡도'] = busResult['승차인원']/busResult['운행대수']
busResult = busResult.sort_values(by='혼잡도')
busResult
Out[4]:
행정동 승차인원 운행대수 혼잡도
20 구기동 158 1946 0.081192
13 홍지동 716 1539 0.465237
80 사근동 2485 2633 0.943790
12 연희동 4319 4281 1.008876
22 평창동 940 502 1.872510
... ... ... ... ...
275 독산2동 36387 537 67.759777
362 송파1동 35906 426 84.286385
304 노량진2동 27889 320 87.153125
37 다산동 9055 98 92.397959
109 전농2동 26489 136 194.772059

399 rows × 4 columns

In [5]:
busResult.to_excel('./busConfusion.xlsx')
In [5]:
fig = go.Figure()
fig.add_trace(go.Scatter(x=busResult['행정동'], y=busResult['혼잡도'], mode='lines', name='Congestion of bus'))
average_get_on = [busResult['혼잡도'].mean()] * len(busResult)
fig.add_trace(go.Scatter(x=busResult['행정동'], y=average_get_on, mode='lines', name='AVERAGE'))
fig.update_layout(
    title='Bus Congestion',
    xaxis_title='행정동',
    yaxis_title='Congestion',
    xaxis_rangeslider_visible=True  # rangeslider 추가
)

# plotly 그래프 출력
fig.show()
In [6]:
busResult_mean = busResult['승차인원'].mean()
busResult_mean
Out[6]:
26290.44611528822
In [7]:
fig = go.Figure()
fig.add_trace(go.Scatter(x=busResult['행정동'], y=busResult['승차인원'], mode='lines', name='GET ON'))
average_get_on = [busResult['승차인원'].mean()] * len(busResult)
fig.add_trace(go.Scatter(x=busResult['행정동'], y=average_get_on, mode='lines', name='AVERAGE'))
fig.update_layout(
    title='탑승인원',
    xaxis_title='행정동',
    yaxis_title='탑승인원',
    xaxis_rangeslider_visible=True  # rangeslider 추가
)

# plotly 그래프 출력
fig.show()
In [8]:
fig = go.Figure()
average_working_bus = [busResult['운행대수'].mean()] * len(busResult)
fig.add_trace(go.Scatter(x=busResult['행정동'], y=average_working_bus, mode='lines', name='AVERAGE'))
fig.add_trace(go.Scatter(x=busResult['행정동'], y=busResult['운행대수'], mode='lines', name='WORKING BUS'))
fig.update_layout(
    title='운행대수',
    xaxis_title='행정동',
    yaxis_title='운행대수',
    xaxis_rangeslider_visible=True  # rangeslider 추가
)

# plotly 그래프 출력
fig.show()
In [9]:
localDong = pd.read_csv('./data/LOCAL_PEOPLE_DONG.csv')
localDong.head()
Out[9]:
기준일ID 시간대구분 행정동코드 총생활인구수
0 20230701 0 11140680 7387.6458
1 20230701 0 11230730 21126.2155
2 20230701 0 11380632 14489.8440
3 20230701 0 11380650 10987.3091
4 20230701 0 11380625 43851.1827
In [10]:
hangCode = pd.read_excel('./data/행정동코드.xlsx')
hangCode.head()
Out[10]:
행정동코드 시도명 시군구명 행정동
0 11110530 서울 종로구 사직동
1 11110540 서울 종로구 삼청동
2 11110550 서울 종로구 부암동
3 11110560 서울 종로구 평창동
4 11110570 서울 종로구 무악동
In [11]:
#행정동별 생활인구수
localPP = pd.merge(localDong, hangCode, on='행정동코드', how='inner')
localPP = localPP.drop(columns=['시간대구분'])
localPP = localPP.groupby('행정동', as_index=False)['총생활인구수'].mean()
localPP
Out[11]:
행정동 총생활인구수
0 가락1동 31985.669088
1 가락2동 26452.145546
2 가락본동 34019.237987
3 가리봉동 9798.276317
4 가산동 38799.521196
... ... ...
418 효창동 8450.758638
419 후암동 12282.800313
420 휘경1동 16851.335217
421 휘경2동 18609.358113
422 흑석동 30518.453337

423 rows × 2 columns

In [12]:
#행정동별 사업체개수 및 종사자수
localWP = pd.read_excel('./data/사업체현황종사자수.xlsx')
#행정동별 숙박 및 음식점 개수, 종사자수
localAF = pd.read_excel('./data/숙박및음식점.xlsx')
In [13]:
busResult_R = busResult.merge(localPP, on='행정동', how='inner') \
                .merge(localWP, on='행정동', how='inner') \
                .merge(localAF, on='행정동', how='inner')
busResult_R
Out[13]:
행정동 승차인원 운행대수 혼잡도 총생활인구수 사업체수 총종사자수 사업체수_음식및숙박 종사자수_음식및숙박
0 사근동 2485 2633 0.943790 21279.456646 1310 10537 444 1305
1 연희동 4319 4281 1.008876 36262.183429 3420 13243 518 1426
2 평창동 940 502 1.872510 18597.975900 1321 4321 142 481
3 마장동 3632 1802 2.015538 20304.767346 4030 12518 226 561
4 둔촌1동 1134 539 2.103896 4332.939179 36 286 2 8
... ... ... ... ... ... ... ... ... ...
381 독산2동 36387 537 67.759777 13981.066521 1531 4184 212 381
382 송파1동 35906 426 84.286385 29260.778138 3406 16572 511 1700
383 노량진2동 27889 320 87.153125 16756.667812 2011 6809 258 565
384 다산동 9055 98 92.397959 14017.096233 2023 8723 215 633
385 전농2동 26489 136 194.772059 15133.874650 1358 5460 149 404

386 rows × 9 columns

In [14]:
import warnings
warnings.filterwarnings("ignore")
correlation_matrix = busResult_R.corr().round(2)
sns.heatmap(data=correlation_matrix, annot=True, cmap='bwr')
Out[14]:
<Axes: >
In [ ]: